package br.com.projeto.model.persistencia.daos;

import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;

import br.com.projeto.model.entities.Arquivo;
import br.com.projeto.model.entities.Atividade;
import br.com.projeto.model.entities.Equipe;
import br.com.projeto.model.entities.Fase;
import br.com.projeto.model.entities.Historico;
import br.com.projeto.model.entities.Mensagem;
import br.com.projeto.model.entities.Projeto;
import br.com.projeto.model.entities.Versao;
import br.com.projeto.model.entities.valueobjects.Acao;
import br.com.projeto.model.entities.valueobjects.Referencia;
import br.com.projeto.model.entities.valueobjects.Tipo;
import br.com.projeto.model.persistencia.DAO;
import br.com.projeto.model.persistencia.EntityManagerHelper;
import br.com.projeto.model.persistencia.HistoricoDecorator;

public class HistoricoDAO extends DAO<Historico> {

	private EntityManager context;

	private Historico registro;

	private HistoricoDAO(EntityManager context) {
		super(Historico.class);
		this.context = context;
		this.registro = new Historico();
		this.registro.setData(new Date());
	}

	public static HistoricoDAO registrar(EntityManager context) {
		return new HistoricoDAO(context);
	}

	@SuppressWarnings("unchecked")
	public static List<Historico> listar(Equipe equipe, Projeto projeto,
			int total) {

		EntityManager context = EntityManagerHelper.getEntityManager();

		List<Historico> entradas = (List<Historico>) context
				.createQuery(
						"from Historico h where h.equipe.id = :equipe AND (:projeto = 0 OR h.projeto.id = :projeto) ORDER BY h.data DESC")
				.setParameter("equipe", equipe.getId()).setParameter("projeto",
						projeto == null ? 0 : projeto.getId()).setMaxResults(
						total).getResultList();

		for (Historico historico : entradas) {
			HistoricoDecorator.decorate(historico, context);
		}
		return entradas;
	}

	public void novaAtividade(Atividade atividade) {

		this.registro.setAcao(Acao.CRIAR);
		this.registro.setEquipe(atividade.getAutor().getEquipe());
		this.registro.setInstancia(atividade.getId());
		this.registro.setProjeto(atividade.getProjeto());
		this.registro.setReferencia(Referencia.ATIVIDADE);
		this.registro.setTipo(Tipo.ATIVIDADE);

		this.context.persist(this.registro);
	}

	public void atividadeFinalizada(Atividade atividade) {

		this.registro.setAcao(Acao.FINALIZAR);
		this.registro.setEquipe(atividade.getAutor().getEquipe());
		this.registro.setInstancia(atividade.getId());
		this.registro.setProjeto(atividade.getProjeto());
		this.registro.setReferencia(Referencia.ATIVIDADE);
		this.registro.setTipo(Tipo.ATIVIDADE);

		this.context.persist(this.registro);

	}

	public void novoArquivo(Arquivo arquivo, Versao versao) {
		this.registro.setAcao(Acao.CRIAR);
		this.registro.setEquipe(versao.getUsuario().getEquipe());
		this.registro.setInstancia(arquivo.getId());
		this.registro.setProjeto(arquivo.getProjeto());
		this.registro.setReferencia(Referencia.ARQUIVO);
		this.registro.setTipo(Tipo.ARQUIVO);

		this.context.persist(this.registro);
	}

	public void novaVersao(Arquivo arquivo, Versao versao) {
		this.registro.setAcao(Acao.ATUALIZAR);
		this.registro.setEquipe(versao.getUsuario().getEquipe());
		this.registro.setInstancia(arquivo.getId());
		this.registro.setProjeto(arquivo.getProjeto());
		this.registro.setReferencia(Referencia.ARQUIVO);
		this.registro.setTipo(Tipo.ARQUIVO);

		this.context.persist(this.registro);
	}

	public void novaMensagem(Mensagem mensagem) {
		this.registro.setAcao(Acao.CRIAR);
		this.registro.setEquipe(mensagem.getAutor().getEquipe());
		this.registro.setInstancia(mensagem.getId());
		this.registro.setProjeto(mensagem.getProjeto());
		this.registro.setReferencia(Referencia.MENSAGEM);
		this.registro.setTipo(Tipo.MENSAGEM);

		this.context.persist(this.registro);
	}

	public void novoComentario(Mensagem mensagem) {
		this.registro.setAcao(Acao.ATUALIZAR);
		this.registro.setEquipe(mensagem.getAutor().getEquipe());
		this.registro.setInstancia(mensagem.getId());
		this.registro.setProjeto(mensagem.getProjeto());
		this.registro.setReferencia(Referencia.MENSAGEM);
		this.registro.setTipo(Tipo.MENSAGEM);

		this.context.persist(this.registro);
	}

	public void novaFase(Fase fase) {
		this.registro.setAcao(Acao.CRIAR);
		this.registro.setEquipe(fase.getUsuario().getEquipe());
		this.registro.setInstancia(fase.getId());
		this.registro.setProjeto(fase.getProjeto());
		this.registro.setReferencia(Referencia.FASE);
		this.registro.setTipo(Tipo.FASE);

		this.context.persist(this.registro);
	}

}
